package cn.sciento.autoconfigure.transfer;

import cn.sciento.resource.annoation.EnableSTongResourceServer;
import cn.sciento.transfer.infra.properties.StongTransferProperties;
import cn.sciento.transfer.infra.rocketmq.config.MqConfigProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@ComponentScan({"data.check", "liquibase.parser", "cn.sciento.transfer.api", "cn.sciento.transfer.app", "cn.sciento.transfer.config", "cn.sciento.transfer.domain", "cn.sciento.transfer.infra"})
@EnableFeignClients({"cn.sciento", "io.choerodon"})
@EnableSTongResourceServer
@EnableConfigurationProperties({StongTransferProperties.class, MqConfigProperties.class})
@EnableAsync
@Configuration
public class TransferAutoConfiguration {
  private StongTransferProperties rootProperties;
  
  public TransferAutoConfiguration(StongTransferProperties stongTransferProperties) {
    this.rootProperties = stongTransferProperties;
  }
  
  @Bean
  @Qualifier("asyncTaskExecutor")
  public AsyncTaskExecutor asyncTaskExecutor() {
    StongTransferProperties.ThreadPoolProperties threadPoolProperties = this.rootProperties.getThreadPoolProperties();
    if (threadPoolProperties == null)
      threadPoolProperties = new StongTransferProperties.ThreadPoolProperties();
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
    executor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
    executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
    executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
    executor.setAllowCoreThreadTimeOut(threadPoolProperties.isAllowCoreThreadTimeOut());
    executor.setThreadNamePrefix(threadPoolProperties.getThreadNamePrefix());
    return executor;
  }
  
  @Bean
  @Qualifier("stong-transfer-executor")
  public AsyncTaskExecutor addMsgAsyncTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("stong-transfer-executor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  @Qualifier("stong-transfer-topic-create")
  public AsyncTaskExecutor createTopicAsyncTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("stong-transfer-topic-create");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  public DefaultRedisScript<String> distributionIdGeneratorLua() {
    DefaultRedisScript<String> defaultRedisScript = new DefaultRedisScript();
    defaultRedisScript.setLocation(new ClassPathResource("lua/distribution-id-generator-EN.lua"));
    defaultRedisScript.setResultType(String.class);
    return defaultRedisScript;
  }
  
  @Bean
  @Qualifier("transferSourceTaskExecutor")
  public AsyncTaskExecutor transferSourceTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("transferSourceTaskExecutor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  @Qualifier("transferTargetTaskExecutor")
  public AsyncTaskExecutor transferTargetTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("transferTargetTaskExecutor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  @Qualifier("transferDataCheckExecutor")
  public AsyncTaskExecutor transferDataCheckExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("transferDataCheckExecutor");
    executor.setQueueCapacity(2147483647);
    executor.setMaxPoolSize(1);
    executor.setCorePoolSize(1);
    return executor;
  }
  
  @Bean
  @Qualifier("transferDataCheckSaveFileExecutor")
  public AsyncTaskExecutor transferDataCheckSaveFileExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("transferDataCheckExecutor");
    executor.setQueueCapacity(2147483647);
    executor.setMaxPoolSize(2);
    executor.setCorePoolSize(2);
    return executor;
  }
}
